"""
优惠券系统模块
管理用户优惠券的发放、使用和验证
"""

import json
from pathlib import Path
from typing import Dict, Any, List, Optional
from datetime import datetime, timedelta
import uuid

# 优惠券数据存储路径
COUPONS_DATA_PATH = Path(__file__).parent.parent / "data" / "user_coupons.json"

def _initialize_coupons_data():
    """初始化优惠券数据文件"""
    if not COUPONS_DATA_PATH.exists():
        # 创建数据目录
        COUPONS_DATA_PATH.parent.mkdir(parents=True, exist_ok=True)
        
        default_data = {
            "user_coupons": {},
            "coupon_history": [],
            "created_at": datetime.now().isoformat()
        }
        with open(COUPONS_DATA_PATH, 'w', encoding='utf-8') as f:
            json.dump(default_data, f, ensure_ascii=False, indent=2)
        return default_data
    
    try:
        with open(COUPONS_DATA_PATH, 'r', encoding='utf-8') as f:
            return json.load(f)
    except Exception as e:
        print(f"读取优惠券数据文件失败: {e}")
        return {
            "user_coupons": {},
            "coupon_history": [],
            "created_at": datetime.now().isoformat()
        }

def _save_coupons_data(data: Dict[str, Any]) -> bool:
    """保存优惠券数据"""
    try:
        # 确保目录存在
        COUPONS_DATA_PATH.parent.mkdir(parents=True, exist_ok=True)
        
        with open(COUPONS_DATA_PATH, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        return True
    except Exception as e:
        print(f"保存优惠券数据失败: {e}")
        return False

def issue_coupon(user_id: str, coupon_type: str, value: float, min_amount: float = 0, 
                 validity_days: int = 30, source: str = "points_exchange") -> Dict[str, Any]:
    """发放优惠券"""
    data = _initialize_coupons_data()
    
    # 生成优惠券ID
    coupon_id = f"CPN_{datetime.now().strftime('%Y%m%d%H%M%S')}_{uuid.uuid4().hex[:8].upper()}"
    
    # 创建优惠券
    coupon = {
        "id": coupon_id,
        "user_id": user_id,
        "type": coupon_type,
        "value": value,
        "min_amount": min_amount,
        "issued_date": datetime.now().isoformat(),
        "expires_date": (datetime.now() + timedelta(days=validity_days)).isoformat(),
        "used": False,
        "used_date": None,
        "source": source,
        "order_id": None
    }
    
    # 添加到用户优惠券列表
    if user_id not in data["user_coupons"]:
        data["user_coupons"][user_id] = []
    
    data["user_coupons"][user_id].append(coupon)
    
    # 记录发放历史
    history_record = {
        "action": "issue",
        "coupon_id": coupon_id,
        "user_id": user_id,
        "type": coupon_type,
        "value": value,
        "timestamp": datetime.now().isoformat(),
        "source": source
    }
    data["coupon_history"].append(history_record)
    
    # 保存数据
    _save_coupons_data(data)
    
    return {
        "success": True,
        "message": f"优惠券发放成功",
        "coupon_id": coupon_id,
        "coupon": coupon
    }

def get_user_coupons(user_id: str, only_valid: bool = True) -> List[Dict[str, Any]]:
    """获取用户所有（可用）优惠券"""
    data = _initialize_coupons_data()
    coupons = data["user_coupons"].get(user_id, [])
    now = datetime.now()
    result = []
    for c in coupons:
        if only_valid and (c["used"] or datetime.fromisoformat(c["expires_date"]) < now):
            continue
        result.append(c)
    return result

def get_user_coupons(user_id: str, include_expired: bool = False, include_used: bool = False) -> List[Dict[str, Any]]:
    """获取用户优惠券列表"""
    data = _initialize_coupons_data()
    user_coupons = data["user_coupons"].get(user_id, [])
    
    filtered_coupons = []
    current_time = datetime.now()
    
    for coupon in user_coupons:
        # 检查是否过期
        expires_date = datetime.fromisoformat(coupon["expires_date"])
        is_expired = current_time > expires_date
        is_used = coupon.get("used", False)
        
        # 根据参数过滤
        if not include_expired and is_expired:
            continue
        if not include_used and is_used:
            continue
        
        # 添加状态信息
        coupon_copy = coupon.copy()
        coupon_copy["is_expired"] = is_expired
        coupon_copy["status"] = "已使用" if is_used else ("已过期" if is_expired else "可使用")
        
        filtered_coupons.append(coupon_copy)
    
    # 按发放时间倒序排列
    filtered_coupons.sort(key=lambda x: x["issued_date"], reverse=True)
    
    return filtered_coupons

def get_available_coupons_for_order(user_id: str, order_amount: float) -> List[Dict[str, Any]]:
    """获取订单可用的优惠券"""
    available_coupons = []
    user_coupons = get_user_coupons(user_id, include_expired=False, include_used=False)
    
    for coupon in user_coupons:
        if coupon["type"] == "coupon" and order_amount >= coupon.get("min_amount", 0):
            # 计算优惠后金额
            discount_amount = min(coupon["value"], order_amount)
            final_amount = order_amount - discount_amount
            
            coupon_info = coupon.copy()
            coupon_info["discount_amount"] = discount_amount
            coupon_info["final_amount"] = final_amount
            coupon_info["savings"] = discount_amount
            
            available_coupons.append(coupon_info)
        elif coupon["type"] == "free_shipping":
            # 免运费券
            coupon_info = coupon.copy()
            coupon_info["discount_amount"] = 0  # 免运费不影响商品金额
            coupon_info["final_amount"] = order_amount
            coupon_info["savings"] = 10  # 假设运费为10元
            
            available_coupons.append(coupon_info)
    
    # 按优惠金额排序
    available_coupons.sort(key=lambda x: x.get("savings", 0), reverse=True)
    
    return available_coupons

def use_coupon(user_id: str, coupon_id: str) -> Dict[str, Any]:
    """核销优惠券"""
    data = _initialize_coupons_data()
    coupons = data["user_coupons"].get(user_id, [])
    for c in coupons:
        if c["id"] == coupon_id and not c["used"]:
            c["used"] = True
            c["used_date"] = datetime.now().isoformat()
            _save_coupons_data(data)
            return {"success": True, "coupon": c}
    return {"success": False, "message": "优惠券不存在或已使用"}

def use_coupon(user_id: str, coupon_id: str, order_id: str, order_amount: float) -> Dict[str, Any]:
    """使用优惠券"""
    data = _initialize_coupons_data()
    
    # 查找优惠券
    user_coupons = data["user_coupons"].get(user_id, [])
    coupon = None
    coupon_index = -1
    
    for i, c in enumerate(user_coupons):
        if c["id"] == coupon_id:
            coupon = c
            coupon_index = i
            break
    
    if not coupon:
        return {"success": False, "message": "优惠券不存在"}
    
    # 检查优惠券状态
    if coupon.get("used", False):
        return {"success": False, "message": "优惠券已使用"}
    
    # 检查是否过期
    expires_date = datetime.fromisoformat(coupon["expires_date"])
    if datetime.now() > expires_date:
        return {"success": False, "message": "优惠券已过期"}
    
    # 检查使用条件
    if coupon["type"] == "coupon" and order_amount < coupon.get("min_amount", 0):
        return {"success": False, "message": f"订单金额不满足使用条件（需满{coupon['min_amount']}元）"}
    
    # 计算优惠
    discount_amount = 0
    if coupon["type"] == "coupon":
        discount_amount = min(coupon["value"], order_amount)
    elif coupon["type"] == "free_shipping":
        discount_amount = 0  # 免运费不影响商品金额
    
    final_amount = order_amount - discount_amount
    
    # 标记为已使用
    data["user_coupons"][user_id][coupon_index]["used"] = True
    data["user_coupons"][user_id][coupon_index]["used_date"] = datetime.now().isoformat()
    data["user_coupons"][user_id][coupon_index]["order_id"] = order_id
    
    # 记录使用历史
    history_record = {
        "action": "use",
        "coupon_id": coupon_id,
        "user_id": user_id,
        "order_id": order_id,
        "order_amount": order_amount,
        "discount_amount": discount_amount,
        "final_amount": final_amount,
        "timestamp": datetime.now().isoformat()
    }
    data["coupon_history"].append(history_record)
    
    # 保存数据
    _save_coupons_data(data)
    
    return {
        "success": True,
        "message": "优惠券使用成功",
        "coupon": coupon,
        "discount_amount": discount_amount,
        "final_amount": final_amount,
        "original_amount": order_amount
    }

def get_coupon_statistics(user_id: str = None) -> Dict[str, Any]:
    """获取优惠券统计信息"""
    data = _initialize_coupons_data()
    
    if user_id:
        # 用户个人统计
        user_coupons = data["user_coupons"].get(user_id, [])
        total_coupons = len(user_coupons)
        used_coupons = len([c for c in user_coupons if c.get("used", False)])
        
        current_time = datetime.now()
        expired_coupons = len([c for c in user_coupons 
                              if not c.get("used", False) and 
                              datetime.fromisoformat(c["expires_date"]) < current_time])
        
        available_coupons = total_coupons - used_coupons - expired_coupons
        
        return {
            "user_id": user_id,
            "total_coupons": total_coupons,
            "used_coupons": used_coupons,
            "expired_coupons": expired_coupons,
            "available_coupons": available_coupons
        }
    else:
        # 系统全局统计
        all_coupons = []
        for user_coupons in data["user_coupons"].values():
            all_coupons.extend(user_coupons)
        
        total_issued = len(all_coupons)
        total_used = len([c for c in all_coupons if c.get("used", False)])
        
        return {
            "total_issued": total_issued,
            "total_used": total_used,
            "usage_rate": (total_used / total_issued * 100) if total_issued > 0 else 0
        }

def clean_expired_coupons(user_id: str = None) -> Dict[str, Any]:
    """清理过期优惠券"""
    data = _initialize_coupons_data()
    current_time = datetime.now()
    removed_count = 0
    
    if user_id:
        # 清理指定用户的过期优惠券
        if user_id in data["user_coupons"]:
            original_count = len(data["user_coupons"][user_id])
            data["user_coupons"][user_id] = [
                c for c in data["user_coupons"][user_id]
                if not (not c.get("used", False) and 
                       datetime.fromisoformat(c["expires_date"]) < current_time)
            ]
            removed_count = original_count - len(data["user_coupons"][user_id])
    else:
        # 清理所有用户的过期优惠券
        for uid in data["user_coupons"]:
            original_count = len(data["user_coupons"][uid])
            data["user_coupons"][uid] = [
                c for c in data["user_coupons"][uid]
                if not (not c.get("used", False) and 
                       datetime.fromisoformat(c["expires_date"]) < current_time)
            ]
            removed_count += original_count - len(data["user_coupons"][uid])
    
    # 保存数据
    _save_coupons_data(data)
    
    return {
        "success": True,
        "message": f"已清理{removed_count}张过期优惠券",
        "removed_count": removed_count
    }
